package com.anfeng.cms.service.impl.org;

import com.anfeng.cms.common.Common;
import com.anfeng.cms.domain.org.AfDepartment;
import com.anfeng.cms.repository.mysql.dao.org.AfDepartmentMapper;
import com.anfeng.cms.request.org.DepartDTO;
import com.anfeng.cms.service.org.IAfDepartmentService;
import com.anfeng.cms.util.IdGeneratorUtil;
import com.anfeng.cms.util.JsonMapper;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 吴朋
 * @since 2019-07-15
 */
@Service
@Slf4j
public class AfDepartmentServiceImpl extends ServiceImpl<AfDepartmentMapper, AfDepartment> implements IAfDepartmentService {

    /**
     * 根据上级部门id 和 部门名称 增加 部门信息
     *
     * @param parentId 上级部门id
     * @param deptName 新增部门名称
     * @return 部门id
     */
    @Override
    public String addDepartment(String parentId, String deptName) {
        if (StringUtils.isBlank(deptName)) {
            log.error("根据新增下级 部门 失败  传入参数deptName: {} 为空", deptName);
            return null;
        }
        // 查询上级部门
        AfDepartment parentDept = this.getDepartmentInfo(parentId);
        if (null == parentDept) {
            // 直接增加根部门
            String id = IdGeneratorUtil.uuid();
            parentDept = new AfDepartment();
            parentDept.setName(deptName);
            parentDept.setRemark(deptName);
            parentDept.setId(id);
            parentDept.setState(Common.DATA_STATE_NORMAL);
            parentDept.setParentId(null);
            Date currentDate = new Date();
            parentDept.setCreateTime(currentDate);
            parentDept.setModifiedTime(currentDate);
            boolean insert = this.insert(parentDept);
            if (!insert) {
                log.error("新增根目录失败 {}", deptName);
                return null;
            }
            return id;
        }
        // 存在的话 判断该部门下是否存在相同名称的部门
        AfDepartment department = this.getDepartmentInfo(parentId, deptName);
        // 如果已经存在的话 就直接返回原来的部门id
        if (null != department) {
            log.info("根据上级部门id 和 新部门名称 增加部门信息 部门已存在 无需再次增加");
            return department.getId();
        }
        // 不存在 新增
        department = new AfDepartment();
        String depId = IdGeneratorUtil.uuid();
        department.setId(depId);
        department.setParentId(parentId);
        department.setName(deptName);
        department.setState(Common.DATA_STATE_NORMAL);
        String remark = parentDept.getRemark() + "/" + deptName;
        department.setRemark(remark);
        Date currentDate = new Date();
        department.setCreateTime(currentDate);
        department.setModifiedTime(currentDate);
        boolean result = this.insert(department);
        if (!result) {
            log.error("新增部门失败 上级部门id: {}  新部门名称:{}", parentId, deptName);
            return null;
        }
        return depId;
    }

    /**
     * 根据部门id 逻辑删除部门信息  如果是上级部门的话  下级部门也进行删除
     *
     * @param deptId 部门id
     * @return 是否成功  1 成功  -1 失败
     */
    @Override
    public int deleteDepartment(String deptId) {
        if (StringUtils.isBlank(deptId)) {
            log.error("删除部门信息 传入部门id 为空");
            return Common.RETURN_FAILED;
        }
        // 获取部门信息
        AfDepartment department = this.getDepartmentInfo(deptId);
        if (null == department) {
            log.info("根据部门id 未查询到相关的部门信息 默认删除成功");
            return Common.RETURN_SUCCESS;
        }
        department.setState(Common.DATA_STATE_DELETE);
        department.setModifiedTime(new Date());
        boolean result = this.updateById(department);
        if (!result) {
            log.error("根据部门id:{} 删除部门信息失败", deptId);
            return Common.RETURN_FAILED;
        }
        // 查看是否拥有下级部门
        List<AfDepartment> subDepartments = this.getSubDepartments(deptId);
        if (null != subDepartments && !subDepartments.isEmpty()) {
            subDepartments.forEach(dept -> {
                dept.setState(Common.DATA_STATE_DELETE);
                dept.setModifiedTime(new Date());
            });
            boolean batchResult = this.updateBatchById(subDepartments);
            if (!batchResult) {
                log.error("逻辑删除子部门信息失败 上级部门id：{}", deptId);
                return Common.RETURN_FAILED;
            }
        }

        return Common.RETURN_SUCCESS;
    }

    /**
     * 根据部门id 获取该部门的下属部门
     *
     * @param deptId 部门id
     * @return 下属部门信息
     */
    @Override
    public List<AfDepartment> getSubDepartments(String deptId) {
        if (StringUtils.isBlank(deptId)) {
            log.error("根据部门id 获取子部门信息 传入参数为空");
            return Collections.EMPTY_LIST;
        }
        AfDepartment department = new AfDepartment();
        department.setState(Common.DATA_STATE_NORMAL);
        department.setParentId(deptId);

        EntityWrapper<AfDepartment> wrapper = new EntityWrapper<>();
        wrapper.setEntity(department);
        return this.selectList(wrapper);
    }

    /**
     * 根据id 获取 部门信息
     *
     * @param deptId 部门id
     * @return 部门信息
     */
    @Override
    public AfDepartment getDepartmentInfo(String deptId) {
        if (StringUtils.isBlank(deptId)) {
            log.error("根据deptId 查询 部门信息 传入参数 为 null");
            return null;
        }
        AfDepartment department = new AfDepartment();
        department.setState(Common.DATA_STATE_NORMAL);
        EntityWrapper<AfDepartment> wrapper = new EntityWrapper<AfDepartment>();
        wrapper.setEntity(department);
        return this.selectOne(wrapper);
    }

    /**
     * 根据上级部门id 和 所查部门名称 查询部门信息
     *
     * @param parentId 上级部门id
     * @param deptName 所查询部门名称
     * @return 部门信息
     */
    @Override
    public AfDepartment getDepartmentInfo(String parentId, String deptName) {
        if (StringUtils.isBlank(deptName)) {
            log.error("根据deptName 查询 部门信息 传入参数 为 null");
            return null;
        }
        AfDepartment department = new AfDepartment();
        department.setState(Common.DATA_STATE_NORMAL);
        department.setName(deptName);
        department.setParentId(parentId);

        EntityWrapper<AfDepartment> wrapper = new EntityWrapper<AfDepartment>();
        wrapper.setEntity(department);
        return this.selectOne(wrapper);
    }

    /**
     * 根据部门id 修改部门名称
     *
     * @param deptId     部门id
     * @param department 部门信息
     * @return 是否成功 -1 失败  1 成功
     */
    @Override
    public int updateDepartmentInfo(String deptId, AfDepartment department) {
        if (StringUtils.isBlank(deptId) || StringUtils.isBlank(department.getId()) || !deptId.equals(department.getId())) {
            log.error("根据部门id 修改部门信息失败  传入的参数 有误");
            return Common.RETURN_FAILED;
        }

        AfDepartment dbDept = this.getDepartmentInfo(deptId);
        if (null == dbDept) {
            log.error("根据deptId:{} 未查询到相关部门信息", deptId);
            return Common.RETURN_FAILED;
        }
        //修改信息
        dbDept.setParentId(department.getParentId());
        dbDept.setName(department.getName());
        dbDept.setModifiedTime(new Date());
        boolean result = this.updateById(dbDept);
        if (!result) {
            log.error("更新部门信息失败 deptId:{}, 修改信息为 {}", deptId, JsonMapper.defaultMapper().toJson(department));
            return Common.RETURN_FAILED;
        }
        return Common.RETURN_SUCCESS;
    }

    /**
     * 获取组织树结构
     *
     * @return 组织结构
     */
    @Override
    public List<DepartDTO> getOrganizationTree() {

        List<DepartDTO> departDTOS = new ArrayList<>();

        // 现获取一级部门信息
        List<AfDepartment> rootDepartments = this.getRootDepartments();
        if (null == rootDepartments || rootDepartments.isEmpty()) {
            return Collections.EMPTY_LIST;
        }

        for (AfDepartment rootDept : rootDepartments) {
            DepartDTO departDTO = new DepartDTO();
            departDTO.setId(rootDept.getId());
            departDTO.setParentId(rootDept.getParentId());
            departDTO.setName(rootDept.getName());
            this.getSubDepartments(departDTO);
            departDTOS.add(departDTO);
        }
        return departDTOS;
    }

    /**
     * 获取根部门组织 可能一个
     *
     * @return 部门信息
     */
    @Override
    public List<AfDepartment> getRootDepartments() {
        AfDepartment department = new AfDepartment();
        department.setState(Common.DATA_STATE_NORMAL);
        EntityWrapper<AfDepartment> wrapper = new EntityWrapper<>();
        wrapper.setEntity(department);
        wrapper.isNull("parent_id");
        return this.selectList(wrapper);
    }

    /**
     * 获取所有的最下级组织
     *
     * @return 部门
     */
    @Override
    public List<AfDepartment> getAllSubDepartments() {
        //TODO
        return null;
    }

    /**
     * 根据备注新增部门信息
     *
     * @param remark 备注 （A/B/C）
     * @return 是否成功 -1 失败 1 成功
     */
    @Override
    public int addDepartmentByRemark(String remark) {
        if (StringUtils.isBlank(remark)) {
            log.error("新增部门信息失败 传入参数为null");
            return Common.RETURN_FAILED;
        }
        // 根据remark进行判断截取
        String[] departs = remark.split("/");
        boolean isExist = true;
        String parentId = null;
        for (int i = 0, len = departs.length; i < len; i++) {
            String dept = departs[i];
            if (isExist) {
                AfDepartment departmentInfo = this.getDepartmentInfo(parentId, dept);
                if (departmentInfo != null) {
                    parentId = departmentInfo.getId();
                } else {
                    isExist = false;
                }
            } else {
                //新增
                String deptId = this.addDepartByRemark(parentId, dept);
                if (StringUtils.isBlank(deptId)) {
                    log.error("新增部门信息失败 parentId:{} deptName:{}", parentId, dept);
                    return Common.RETURN_FAILED;
                }
            }
        }
        return Common.RETURN_SUCCESS;
    }

    /**
     * 根据上级id 和 部门名称新增部门信息
     * @param parentId 上级id
     * @param deptName 部门名称
     * @return 新增部门id
     */
    private String addDepartByRemark(String parentId, String deptName) {
        if (StringUtils.isBlank(deptName)) {
            log.error("根据上级id 和 部门名称新增部门信息 传入参数为null");
            return null;
        }
        String deptId = null;
        // 如果新建部门上级不存在 则 默认为第一级部门
        if (StringUtils.isBlank(parentId)) {
            deptId = IdGeneratorUtil.uuid();
            AfDepartment afDepartment = new AfDepartment();
            afDepartment.setRemark(deptName);
            afDepartment.setParentId(null);
            afDepartment.setName(deptName);
            afDepartment.setState(Common.DATA_STATE_NORMAL);
            afDepartment.setId(deptId);
            Date currentDate = new Date();
            afDepartment.setCreateTime(currentDate);
            afDepartment.setModifiedTime(currentDate);
            boolean insert = this.insert(afDepartment);
            if (!insert) {
                log.error("新增一级部门失败 部门名称 {}", deptName);
                return null;
            }
        } else {
            deptId = this.addDepartment(parentId, deptName);
        }
        return deptId;
    }

    /**
     * 根据remark获取部门信息
     *
     * @param remark 备注信息
     * @return 部门信息
     */
    @Override
    public AfDepartment getDepartmentByRemark(String remark) {
        if (StringUtils.isBlank(remark)) {
            log.error("根据remark 查询部门信息失败 传入参数为null");
            return null;
        }
        EntityWrapper<AfDepartment> wrapper = this.generatorDepartmentWrapper(remark);
        return this.selectOne(wrapper);
    }

    /**
     * 根据部门删除部门及子部门
     *
     * @param deptId 部门id
     * @return 是否成功 -1 失败 1 成功
     */
    @Override
    public int deleteDepartmentAndSub(String deptId) {
        if (StringUtils.isBlank(deptId)) {
            log.error("删除部门信息 部门id 部门为null");
            return Common.RETURN_FAILED;
        }
        List<AfDepartment> departmentList = new ArrayList<>();
        // 获取部门的下级部门
        AfDepartment department = this.getDepartmentInfo(deptId);
        if (null == department) {
            return Common.RETURN_FAILED;
        }
        departmentList.add(department);

        List<AfDepartment> subDepartments = this.getSubDepartments(department.getId());
        if (null != subDepartments && !subDepartments.isEmpty()) {
            for (AfDepartment sub : subDepartments) {
                List<AfDepartment> thirdDep = this.getSubDepartments(department.getId());
                if (null != thirdDep && !thirdDep.isEmpty()) {
                    departmentList.addAll(thirdDep);
                } else {
                    departmentList.add(sub);
                }
            }
        }
        departmentList.forEach(dept->{
            dept.setState(Common.DATA_STATE_DELETE);
            dept.setModifiedTime(new Date());
        });
        boolean update = this.updateBatchById(departmentList);
        if (!update) {
            log.error("删除部门失败 {}", JsonMapper.defaultMapper().toJson(departmentList));
            return Common.RETURN_FAILED;
        }
        return Common.RETURN_SUCCESS;
    }

    /**
     * 根据上级部门获取子部门
     * @param department 上级部门
     */
    private void getSubDepartments(DepartDTO department) {
        if (department == null) {
            return;
        }
        List<AfDepartment> subDepartments = this.getSubDepartments(department.getId());
        if (null == subDepartments || subDepartments.isEmpty()) {
            return;
        }
        List<DepartDTO> subDepts = new ArrayList<>();
        for (AfDepartment subDept : subDepartments) {
            DepartDTO subDep = new DepartDTO();
            subDep.setParentId(department.getId());
            subDep.setId(subDept.getId());
            subDep.setName(subDept.getName());
            getSubDepartments(subDep);
            subDepts.add(subDep);
        }
        department.setSubs(subDepts);
    }

    /**
     * 根据remark创建部门查询语句
     * @param remark remark
     * @return wrapper
     */
    private EntityWrapper<AfDepartment> generatorDepartmentWrapper(String remark) {
        AfDepartment department = new AfDepartment();
        if (StringUtils.isNotBlank(remark)) {
            department.setRemark(remark);
        }
        department.setState(Common.DATA_STATE_NORMAL);
        EntityWrapper<AfDepartment> wrapper = new EntityWrapper<>();
        wrapper.setEntity(department);
        return wrapper;
    }


}
